package main_gui;

import calculation.FIRWindow;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.GroupLayout;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import my_interface.SelectType;
import my_interface.WindowType;

/**
 *
 * @author KieuOanh
 */
public class WindowFrame extends JFrame implements WindowType, SelectType {

    FIRWindow firw;

//    public WindowFrame() {       
//        setBounds(30, 20, 900, 700);
//        setResizable(false);
//        setVisible(true);
//        setTitle("Window");
//    }

    public WindowFrame( FIRWindow firw) {
        this.firw = firw;
        setBounds(30, 20, 900, 700);
        setResizable(false);
        setVisible(true);
        setTitle("Window");
    }

    public void setData(FIRWindow fIRWindow) {
        this.firw = fIRWindow;
    }

       @Override
    public void paint(Graphics g) {
        g.setColor(Color.LIGHT_GRAY);
        g.fillRect(0, 0, 900, 700);
        g.setColor(Color.WHITE);
        g.fillRect(70, 100, 300, 240);
        g.fillRect(70, 415, 300, 240);
        g.fillRect(510, 100, 300, 240);
        g.fillRect(510, 415, 300, 240);

        ///////////////////////////////////////////////////////////////////////
        //ve hd(n)
        double ratio_hd = 200 / (firw.hdMax - firw.hdMin);
        double ratio_hn = 200 / (firw.hnMax - firw.hnMin);
        double ratio_wn = 200 / firw.wnMax;
        double ratio_dB = 215 / firw.dBMax;

        int point0_hd = 100 + (int) (firw.hdMax * 1.2 * ratio_hd);
        int point0_hn = 415 + (int) (firw.hnMax * 1.2 * ratio_hn);
        double d = (double) 300 / firw.M;

        g.setColor(Color.BLUE);
        for (int i = 0; i < firw.M - 1; i++) {
            g.drawLine((int) ((i + 1) * d) + 70, point0_hd, (int) ((i + 1) * d) + 70, (int) (point0_hd - firw.hd[i] * ratio_hd));
            g.drawOval((int) ((i + 1) * d) + 65, (int) (point0_hd - firw.hd[i] * ratio_hd) - 5, 10, 10);

            g.drawLine((int) ((i + 1) * d) + 70, point0_hn, (int) ((i + 1) * d) + 70, (int) (point0_hn - firw.hn[i] * ratio_hn));
            g.drawOval((int) ((i + 1) * d) + 65, (int) (point0_hn - firw.hn[i] * ratio_hn) - 5, 10, 10);

            g.drawLine((int) ((i + 1) * d) + 510, 340, (int) ((i + 1) * d) + 510, (int) (340 - firw.w[i] * ratio_wn));
            g.drawOval((int) ((i + 1) * d) + 505, (int) (335 - firw.w[i] * ratio_wn), 10, 10);
        }
        /////////////////
        int xPrevious = 0;
        int yPrevious = (int) (ratio_dB * firw.dB[0]);

        for (int i = 1; i < 300; i++) {
            int yCurrent = (int) (ratio_dB * firw.dB[i]);
            g.drawLine(xPrevious + 510, 440 + yPrevious, 510 + i, 440 + yCurrent);
            xPrevious = i;
            yPrevious = yCurrent;
        }

        g.setColor(Color.LIGHT_GRAY);
        g.fillRect(510, 341, 300, 20);

        g.setColor(Color.BLACK);
        g.drawLine(70, point0_hd, 370, point0_hd);
        g.drawLine(70, point0_hn, 370, point0_hn);
        double ratioMaxMin;
        double unit;
        int index;

        //window 1
        g.drawString("Ideal Impulse Response", 150, 90);
        g.drawString("hd(n)", 10, 220);
        g.drawString("n", 220, 365);
        g.drawRect(70, 100, 300, 240);
        g.drawString("0", 60, point0_hd + 5);
        ratioMaxMin = firw.hdMax / (-firw.hdMin);

        if (ratioMaxMin > 2) {
            unit = round2(-firw.hdMin);
            index = -1;
        } else {
            unit = round2(-firw.hdMin) / 2;
            index = -2;
        }
        while (index < ratioMaxMin + 2 && (int) (point0_hd - index * unit * ratio_hd) > 100) {
            if (index != 0) {
                g.drawString(trim2(unit * index) + "", 40, point0_hd - (int) (index * unit * ratio_hd) + 5);
                g.drawLine(70, point0_hd - (int) (index * unit * ratio_hd), 73, point0_hd - (int) (index * unit * ratio_hd));
                g.drawLine(370, point0_hd - (int) (index * unit * ratio_hd), 367, point0_hd - (int) (index * unit * ratio_hd));
            }
            index++;
        }
        for (int i = 0; i < 6; i++) {
            g.drawLine(70 + i * 60, 100, 70 + i * 60, 103);
            g.drawLine(70 + i * 60, 340, 70 + i * 60, 337);
            g.drawString(firw.M * i / 5 + "", 63 + i * 60, 355);
        }

        //window2
        String sTypeWindow = null;
        switch (firw.typeWindow) {
            case RECTANGLE:
                sTypeWindow = "Rectangle window";
                break;
            case BARTLETT:
                sTypeWindow = "Bartlett window";
                break;
            case HANNING:
                sTypeWindow = "Hanning window";
                break;
            case HAMMING:
                sTypeWindow = "Hamming window";
                break;
            case BLACKMAN:
                sTypeWindow = "Black window";
                break;
            case KAISER:
                sTypeWindow = "Kaiser window";
                break;
        }
        g.drawString(sTypeWindow, 600, 90);
        g.drawString("h(n)", 10, 535);
        g.drawString("n", 220, 685);
        g.drawRect(70, 415, 300, 240);
        g.drawString("0", 60, point0_hn + 5);
        ratioMaxMin = firw.hnMax / (-firw.hnMin);
        if (ratioMaxMin > 2) {
            unit = round2(-firw.hnMin);
            index = -1;
        } else {
            unit = round2(-firw.hnMin) / 2;
            index = -2;
        }
        while (index < ratioMaxMin + 1) {
            if (index != 0 && point0_hn - (int) (index * unit * ratio_hn) > 415) {
                g.drawString(trim2(unit * index) + "", 40, point0_hn - (int) (index * unit * ratio_hn) + 5);
                g.drawLine(70, point0_hn - (int) (index * unit * ratio_hn), 73, point0_hn - (int) (index * unit * ratio_hn));
                g.drawLine(370, point0_hn - (int) (index * unit * ratio_hn), 367, point0_hn - (int) (index * unit * ratio_hn));
            }
            index++;
        }
        for (int i = 0; i < 6; i++) {
            g.drawLine(70 + i * 60, 415, 70 + i * 60, 418);
            g.drawLine(70 + i * 60, 655, 70 + i * 60, 652);
            g.drawString(firw.M * i / 5 + "", 63 + i * 60, 670);
        }

        //window 3
        g.drawString("Actual Impulse Response", 150, 405);
        g.drawString("w(n)", 450, 220);
        g.drawString("n", 660, 365);
        g.drawRect(510, 100, 300, 240);
        for (int i = 0; i < 6; i++) {
            g.drawLine(510 + i * 60, 100, 510 + i * 60, 103);
            g.drawLine(510 + i * 60, 340, 510 + i * 60, 337);
            g.drawString(firw.M * i / 5 + "", 503 + i * 60, 355);
            g.drawLine(510, 340 - (int) (ratio_wn * i / 5), 513, 340 - (int) (ratio_wn * i / 5));
            g.drawLine(810, 340 - (int) (ratio_wn * i / 5), 807, 340 - (int) (ratio_wn * i / 5));
            g.drawString(round2(firw.wnMax * i / 5) + "", 485, 345 - (int) (ratio_wn * i / 5));
        }

        //window 4
        g.drawString("Magnitude Response in dB", 600, 405);
        g.drawString("Frequence in pi units", 600, 685);
        g.drawString("Decibels", 430, 550);
        g.drawRect(510, 415, 300, 240);

        g.drawString("" + firw.wp, 503 + (int) (firw.wp * 300), 670);
        g.drawString("" + firw.ws, 503 + (int) (firw.ws * 300), 670);
        for (int i = 0; i < 48; i++) {
            g.drawLine(510 + (int) (firw.wp * 300), 415 + i * 5, 510 + (int) (firw.wp * 300), 416 + i * 5);
            g.drawLine(510 + (int) (firw.ws * 300), 415 + i * 5, 510 + (int) (firw.ws * 300), 416 + i * 5);
        }

        if (firw.typeSelect == BAND_PASS || firw.typeSelect == BAND_STOP) {
            g.drawString("" + firw.w2p, 503 + (int) (firw.w2p * 300), 670);
            g.drawString("" + firw.w2s, 503 + (int) (firw.w2s * 300), 670);
            for (int i = 0; i < 48; i++) {
                g.drawLine(510 + (int) (firw.w2p * 300), 415 + i * 5, 510 + (int) (firw.w2p * 300), 416 + i * 5);
                g.drawLine(510 + (int) (firw.w2s * 300), 415 + i * 5, 510 + (int) (firw.w2s * 300), 416 + i * 5);
            }
        }
        g.drawString("0", 508, 670);
        g.drawString("1", 808, 670);
        g.drawString("" + (int) firw.As, 490, 445 + (int) (firw.As * ratio_dB));
        g.drawString("0", 490, 445);

        for (int i = 0; i < 60; i++) {
            g.drawLine(510 + i * 5, 440, 511 + i * 5, 440);
            g.drawLine(510 + i * 5, 440 + (int) (firw.As * ratio_dB), 511 + i * 5, 440 + (int) (firw.As * ratio_dB));
        }
        g.setFont(new Font("Courier New", Font.BOLD, 20));
        g.drawString("FIR: WINDOW DESIGN TECHNIQUE", 300, 60);
    }

    double trim2(double x) {
        return (int) (x * 100) / (double) 100;
    }

    double round2(double x) {
        return (int) (x * 100 + 0.5) / (double) 100;
    }
}
